package com.example.menuvirtualclient.presenter;

import java.util.List;

import android.graphics.Bitmap;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.menuvirtualclient.*;
import com.example.menuvirtualclient.core.*;
import com.example.menuvirtualclient.repository.CommentRepository;
import com.example.menuvirtualclient.repository.DishRepository;
import com.example.menuvirtualclient.repository.MenuRepository;
import com.example.menuvirtualclient.rule.*;
import com.example.menuvirtualclient.util.Common;
import com.example.menuvirtualclient.util.eMenuOptions;
import com.example.menuvirtualclient.view.*;

public class MenuPresenter implements IMenuPresenter {

	private IView _view;
	private IMenuView _menuView;
	private MenuRule _rule;
	private OrderRule _orderRule;
	private DishRule _dishRule;
	private UserRule _userRule;
	private User _user;
	private OrderDetailRule _orderDetailRule;
	private DishMenuRule _dishMenuRule;
	private TableRule _tableRule;
	private CommentRule _commentRule;
	private ProgressBar pb;

	
	public MenuPresenter(IView view, ProgressBar pb) {
		_view = view;
		_rule = new MenuRule(view.GetContext());
		_orderRule = new OrderRule(view.GetContext());
		_dishRule = new DishRule(view.GetContext());
		_userRule = new UserRule(view.GetContext());
		_orderDetailRule = new OrderDetailRule(view.GetContext());
		_dishMenuRule = new DishMenuRule(view.GetContext());
		_tableRule = new TableRule(view.GetContext());
		_commentRule = new CommentRule(view.GetContext());

		this.pb = pb;
	}

	public MenuPresenter(IView view) {
		_view = view;
		_rule = new MenuRule(view.GetContext());
		_orderRule = new OrderRule(view.GetContext());
		_dishRule = new DishRule(view.GetContext());
		_userRule = new UserRule(view.GetContext());
		_orderDetailRule = new OrderDetailRule(view.GetContext());
		_dishMenuRule = new DishMenuRule(view.GetContext());
		_tableRule = new TableRule(view.GetContext());
		_commentRule = new CommentRule(view.GetContext());

	}

	public void LoadMenus() {
		try {
			// WsMenuClient menuClient = new WsMenuClient(_rule,
			// _view.GetContext(), pb);
			// menuClient.execute(Common.URL_WS + "getMenusJson");

			// String request = menuClient.getRequest();
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void saveToTemp(Order order) {
		try {
			_orderRule.saveToTemp(order);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public Order getFromTemp() {
		try {
			return _orderRule.getFromTemp();
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}

	public Menu getMenu(int id) {
		try {
			return _rule.Get(id);
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}

	public List<Menu> getAllMenu() {
		try {
			return _rule.GetEntityList();
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}

	public Dish getDish(int id) {
		try {
			return _dishRule.Get(id);
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}

	public boolean exist(DishComment entity) {
		try {
			return _dishRule.exist(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
		return false;
	}

	public boolean exist(DishMenu entity) {
		try {
			return _dishMenuRule.exist(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
		return false;
	}

	public boolean exist(Table entity) {
		try {
			Table table = _tableRule.Get(entity.getId());
			if (table != null)
				return true;
			else
				return false;
		} catch (Exception ex) {
			HandleException(ex);
		}
		return false;
	}

	public void Insert(Menu entity) {
		try {
			_rule.Insert(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Insert(Dish entity) {
		try {
			_dishRule.Insert(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Insert(DishMenu entity) {
		try {
			_dishMenuRule.Insert(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Insert(Table entity) {
		try {
			_tableRule.Insert(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Update(Menu entity) {
		try {
			_rule.Update(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Update(Table entity) {
		try {
			_tableRule.Update(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Update(Dish entity) {
		try {
			_dishRule.Update(entity);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	// Borro todos los Dishes
	public void deleteAllDishes() {
		try {
			_dishRule.deleteAll();
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	// Borro todos los DishesMenues
	public void deleteAllDishesMenues() {
		try {
			_dishMenuRule.deleteAll();
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	// Borro todos los Menues
	public void deleteAllMenues() {
		try {
			_rule.deleteAll();
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void LoadDishes() {
		/*
		 * try{ WsDishClient dishClient = new WsDishClient(_dishRule);
		 * dishClient.execute(Common.URL_WS + "getAllDishesJson");
		 * 
		 * String request = dishClient.getRequest(); } catch(Exception ex){
		 * HandleException(ex); }
		 */
	}

	public void LoadRestaurant(Restaurant restaurant) {
		try {
			// WsRestauranteClient restauranteClient = new
			// WsRestauranteClient();
			// restauranteClient.execute(Common.URL_WS + "getRestaurantJson");
			// restauranteClient.execute(Common.URL_WS + "getPersona");

			_view.LoadRestaurant(restaurant);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	/*
	 * public void InitView(){ try{ List<Menu> left =
	 * _rule.GetEntityListLeft(1); List<Menu> right =
	 * _rule.GetEntityListRight(1);
	 * 
	 * Menu[] menuRight = right.toArray(new Menu[right.size()]); Menu[] menuLeft
	 * = left.toArray(new Menu[left.size()]); _view.LoadEntityList(menuRight,
	 * menuLeft); } catch(Exception ex){ HandleException(ex); } }
	 */
	/*
	 * public void LoadMenu(int menuId){ try{ List<Menu> left =
	 * _rule.GetEntityListLeft(seccionId); List<Menu> right =
	 * _rule.GetEntityListRight(seccionId); Menu[] menuRight = right.toArray(new
	 * Menu[right.size()]); Menu[] menuLeft = left.toArray(new
	 * Menu[left.size()]);
	 * 
	 * _view.LoadEntityList(menuRight, menuLeft); } catch(Exception ex){
	 * HandleException(ex); } }
	 */

	public void LoadDishes(int menuId) {
		try {
			// List<Dish> dishes = _dishRule.GetDishesByMenu(menuId);
			// Dish[] array = dishes.toArray(new Dish[dishes.size()]);
			_view.LoadEntityList(menuId);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public List<Dish> GetDishesByMenu(int menuId) {
		try {
			List<Dish> dishes = _dishRule.GetDishesByMenu(menuId);
			return dishes;
			// Dish[] array = dishes.toArray(new Dish[dishes.size()]);
			// return array;
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}

	public void LoadMainMenu() {
		try {
			// List<MenuType> list = _seccionRule.GetEntityList();
			// MenuType[] seccion = list.toArray(new MenuType[list.size()]);
			// _view.LoadMainMenu(seccion);
			List<Menu> list = _rule.GetEntityList();
			Menu[] menues = list.toArray(new Menu[list.size()]);
			_view.LoadMainMenu(menues);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void GetOrderMenu(int id) {
		try {
			/*
			 * List<OrderMenuItem> orderMenus =
			 * _orderMenuItem.GetAllByOrder(id); if(orderMenus == null ||
			 * orderMenus.size() == 0) _view.SetMessage("Informaci�n",
			 * "No hay un men� asociada a la orden."); else
			 * _view.GetOrderMenu(orderMenus);
			 */
			List<OrderDetail> orderDetails = _orderDetailRule.GetAllByOrder(id);
			if (orderDetails == null || orderDetails.size() == 0)
				_view.SetMessage("Informaci�n",
						"No hay un plato asociada a la orden.");
			else {
				for (OrderDetail od : orderDetails) {
					od.setComments(_commentRule.GetCommentByDetail(od.getId()));
				}
				_view.GetOrderDetails(orderDetails);
			}
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void SaveOrderDetail(OrderDetail orderDetail) {
		try {
			_orderDetailRule.saveOrderDetail(orderDetail);
			_view.SetMessage("Informaci�n",
					"La orden se envio satisfactoriamente.");
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void SaveDish(int orderId, int dishId, View v) {
		try {
			OrderDetail orderDetail = new OrderDetail();
			Order order = _orderRule.Get(orderId);
			Dish dish = _dishRule.Get(dishId);
			orderDetail.setDish(dish);

			orderDetail.setStatus(1);
			orderDetail.setOrder(order);

			_orderDetailRule.saveOrderDetail(orderDetail);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void RemoveDishToOrder(int orderId, int dishId) {
		try {
			_orderDetailRule.deleteOrderDetail(orderId, dishId);
			WsOrderDetailClient orderClient = new WsOrderDetailClient();
			orderClient.execute(Common.URL_WS + "removeOrderDetail?orderid="
					+ orderId + "&dishid=" + dishId + "&status=1");
			orderClient.getRequest();

			List<OrderDetail> orderDetails = _orderDetailRule.GetAllByOrder(1);
			if (orderDetails == null || orderDetails.size() == 0) {
				// _view.CloseView(v);
				_view.SetMessage("Informaci�n",
						"No hay un men� asociada a la orden.");
			} else
				_view.GetOrderDetails(orderDetails);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void ShowEnquiry() {
		try {
			_view.ShowEnquiry();
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void deleteOrderDetail(int detailId, int orderId) {
		try {
			_orderDetailRule.deleteOrderDetail(detailId);

			List<OrderDetail> orderDetails = _orderDetailRule
					.GetAllByOrder(orderId);
			if (orderDetails == null || orderDetails.size() == 0) {
				// _view.CloseView(v);
				_view.SetMessage("Informaci�n",
						"No hay un men� asociada a la orden.");
			} else
				_view.GetOrderDetails(orderDetails);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Login(String password) {
		try {
			// WsUserClient userClient = new WsUserClient();
			// userClient.execute(Common.URL_WS + "authenticateJson?password=" +
			// password);
			// _user = userClient.getRequest();
			_user = _userRule.Login(password);
			if (_user != null)
				_view.ShowTables();
			else
				_view.SetMessage("Advertencia", "Usuario no encontrado");
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void Login(String userName, String password) {
		try {
			// WsUserClient userClient = new WsUserClient();
			// userClient.execute(Common.URL_WS + "authenticateJson?password=" +
			// password);
			// _user = userClient.getRequest();
			_user = _userRule.Login(userName, password);
			if (_user != null)
				_view.ShowTables();
			else
				_view.SetMessage("Advertencia", "Usuario no encontrado");
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void UpdateOrderDetail(int id, int status, int orderId, int dishId) {
		try {
			OrderDetail orderDetail = _orderDetailRule.Get(id);
			orderDetail.setStatus(status);
			orderDetail.setOrder(new Order(orderId));
			orderDetail.setDish(new Dish(dishId));
			_orderDetailRule.Update(orderDetail);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void UpdateOrderDetail(int id, int cookingPoint) {
		try {
			OrderDetail orderDetail = _orderDetailRule.Get(id);
			orderDetail.setCookingPoint(cookingPoint);
			_orderDetailRule.Update(orderDetail);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void SaveDishComments(List<DishComment> dishComments) {
		try {
			_dishRule.saveDishComment(dishComments);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void SaveComments(List<Comment> comments) {
		try {
			_commentRule.Insert(comments);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public List<Comment> GetCommentByDish(int dishId) {
		try {
			List<Comment> comments = _dishRule.GetCommnetsByDish(dishId);
			// Dish[] array = dishes.toArray(new Dish[dishes.size()]);
			// return array;
			return comments;
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}

	public void deleteComments() {
		try {
			// Borro los datos de la tabla comments y dishes_comments
			_commentRule.deleteComments();
		} catch (Exception ex) {
			HandleException(ex);
		}
	}
	
	public void deleteAllPrices() {
		try {
			// Borro los datos de la tabla comments y dishes_comments
			_dishRule.deleteAllPrices();
		} catch (Exception ex) {
			HandleException(ex);
		}
	}
	
	public void savePrice(List<Price> prices) {
		try {
			// Borro los datos de la tabla comments y dishes_comments
			_dishRule.savePrice(prices);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}
	
	public List<Price> getPriceByDish(int dishId){
		try {
			// Borro los datos de la tabla comments y dishes_comments
			 return _dishRule.getPriceByDish(dishId);
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}

	public void deleteOrderDetailCommentsById(int detailId) {
		try {
			// Borro los datos de la tabla comments y dishes_comments
			_commentRule.deleteOrderDetailCommentsById(detailId);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void saveOrderDetailComment(int orderdetailid, int commentid) {
		try {
			// grabo los datos en la tabla relacional de orderDetail y comments
			_commentRule.saveOrderDetailComment(orderdetailid, commentid);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public void saveOrderDetailComment(int orderdetailid,
			List<Integer> commentid) {
		try {
			// grabo los datos en la tabla relacional de orderDetail y comments
			_commentRule.saveOrderDetailComment(orderdetailid, commentid);
		} catch (Exception ex) {
			HandleException(ex);
		}
	}

	public User getUser() {
		return _user;
	}

	private void HandleException(Exception ex) {
		_view.SetMessage("Error", ex.getMessage());
	}

	@SuppressWarnings("unused")
	private void HandleException(String message) {
		_view.SetMessage("Error", message);
	}

	@Override
	public void setView(Object view) {
		_menuView = (IMenuView) view;
	}

	@Override
	public void toggleMenu() {
		// TODO Auto-generated method stub

	}

	@Override
	public void optionSelected(eMenuOptions option) {
		switch (option) {
		case HOME:
			_menuView.navigate(FullscreenActivity.class);
			break;
		case ENQUIRY:
			_menuView.navigate(EnquiryActivity.class);
			break;
		// case Favorites:
		// Bundle extras = new Bundle();
		// extras.putBoolean("favorites", true);
		// view.navigate(BillBoardActivity.class, extras);
		// break;
		}
	}

	public List<User> getAllUsers() {
		try {
			return _userRule.getAllUsers();
		} catch (Exception ex) {
			HandleException(ex);
		}
		return null;
	}
}
